# file: model.py
from template.engineering_rules import RuleManager
from core.excel_writer import DirectTemplateWriter
from config.path import path_manager
import os
import threading
from concurrent.futures import ThreadPoolExecutor
import pandas as pd
class RuleConfiguration:
    def __init__(self):
        self._rule_modules = [
            {"rule_module": "GL105", "rule_class": "GL105_Rule"},
            # {"rule_module": "JS101", "rule_class": "JS101_Rule"},
            # {"rule_module": "JS103", "rule_class": "JS103_Rule"},
            # {"rule_module": "JS107", "rule_class": "JS107_Rule"},
            # {"rule_module": "JS108", "rule_class": "JS108_Rule"},
            # {"rule_module": "JS111", "rule_class": "JS111_Rule"},
            # {"rule_module": "JS601_1", "rule_class": "JS601_1_Rule"},
            # {"rule_module": "JS703", "rule_class": "JS703_Rule"},
            # {"rule_module": "ZJ403", "rule_class": "ZJ403_Rule"},
            # {"rule_module": "ZJ904", "rule_class": "ZJ904_Rule"},
            # {"rule_module": "ZJ812", "rule_class": "ZJ812_Rule"},
        ]
        self._sheet_write_order = ["GL105", "JS101", "JS103", "JS107", "JS108", "JS601_1", "JS111", "JS703", "ZJ403", "ZJ904", "ZJ812"]

    def get_rule_modules(self):
        return self._rule_modules

    def get_sheet_write_order(self):
        return self._sheet_write_order


class RuleProcessor:
    def __init__(self, rule_config=None):
        self.rule_config = rule_config or RuleConfiguration()
        self.lock = threading.Lock()

    def execute_rule_and_format_data(self, rule_config, project_info, instance_id=None):
        manager = RuleManager()
        result_df = manager.execute_rule(
            rule_module=rule_config["rule_module"],
            rule_class=rule_config["rule_class"],
            project_info=project_info,
        )

        # 强制转换为 DataFrame
        if isinstance(result_df, list):
            result_df = pd.DataFrame(result_df)
        elif isinstance(result_df, dict):
            result_df = pd.DataFrame([result_df])
        elif not isinstance(result_df, pd.DataFrame):
            print(f"[错误] 规则 {rule_config['rule_module']} 返回非 DataFrame 类型: {type(result_df)}")
            result_df = pd.DataFrame()

        data_output = []
        for _, row in result_df.iterrows():
            try:
                processed = row["processed_values"]
                cell_ref = row["单元格编号"]
                sheet_name = row["工作表名称"]

                if isinstance(processed['value'], list):
                    for cell, val in processed['value']:
                        data_output.append({
                            "cell_ref": cell,
                            "value": val,
                            "sheet": sheet_name,
                            "group_key": f"{rule_config['rule_module']}_{instance_id or 'default'}",
                            "project_info": project_info
                        })
                else:
                    data_output.append({
                        "cell_ref": cell_ref,
                        "value": processed["value"],
                        "sheet": sheet_name,
                        "group_key": f"{rule_config['rule_module']}_{instance_id or 'default'}",
                        "project_info": project_info
                    })

            except (KeyError, TypeError) as e:
                data_output.append({
                    "cell_ref": row["单元格编号"],
                    "value": "待补充",
                    "sheet": row["工作表名称"],
                    "group_key": f"{rule_config['rule_module']}_{instance_id or 'default'}",
                    "project_info": project_info
                })

        return data_output

    def merge_and_cleanup(self, project_info, instance_values):
        merged = project_info.copy()
        merged.update(instance_values)
        merged.pop('instance_mapping', None)
        return merged

    def write_project_to_excel(self, project_info, output_dir, output_suffix=None):
        all_data = []
        print("项目基本信息:", project_info)
        instance_mapping = project_info.get("instance_mapping", {})

        for rule_config in self.rule_config.get_rule_modules():
            module_name = rule_config["rule_module"]

            if module_name in instance_mapping:
                for instance_dict in instance_mapping[module_name]:
                    for instance_id, instance_values in instance_dict.items():
                        merged_project_info = {
                            **project_info,
                            "instance_id": instance_id,
                            "instance_module": module_name,
                            "instance_values": instance_values,
                        }
                     
                        module_data = self.execute_rule_and_format_data(rule_config, merged_project_info, instance_id=instance_id)
                        all_data.extend(module_data)
            else:
                merged_project_info = {**project_info}
                module_data = self.execute_rule_and_format_data(rule_config, merged_project_info)
                all_data.extend(module_data)

        path_manager.set_output_base_path(output_dir)
        writer = DirectTemplateWriter(all_data, group_by="group_key")

        with self.lock:
            results = writer.write_all(
                sheet_order=self.rule_config.get_sheet_write_order(),
                output_suffix=output_suffix,
                sub_dir=project_info.get('施工部位')
            )
        return results

    def process_single_project(self, project_info, base_output_folder="outputs"):
        results = []

        if isinstance(project_info, dict) and "project_list" in project_info:
            for proj in project_info['project_list']:
                construction_site = proj.get("施工部位", "未知施工部位")
                output_dir = base_output_folder
                result = self.write_project_to_excel(proj, output_dir)
                results.extend(result)
        else:
            construction_site = project_info.get("施工部位", "未知施工部位")
            output_dir = os.path.join(base_output_folder, construction_site)
            result = self.write_project_to_excel(project_info, output_dir)
            results.extend(result)

        return results

    def run_pipeline_for_projects(self, project_list, base_output_folder="outputs", max_workers=4):
        with ThreadPoolExecutor(max_workers=max_workers) as executor:
            futures = []
            for project_info in project_list:
                future = executor.submit(self.process_single_project, project_info, base_output_folder)
                futures.append(future)

            for future in futures:
                try:    
                    future.result()
                except Exception as e:
                    print(f"任务执行失败: {e}")

        print("\n✅ 所有项目处理完成")

if __name__ == "__main__":
    
    import yaml
    with open(r"/Users/chenhongbin/myapp1/highway-information/YAMLS/圆管涵/项目基本信息_圆管涵(八字墙).yaml", "r", encoding="utf-8") as f:
        config = yaml.safe_load(f)

    project_list = config["project_list"]

    processor = RuleProcessor()
    processor.run_pipeline_for_projects(project_list, base_output_folder="outputs", max_workers=5)
    


